package com.dashu.core.service;

import com.dashu.base.enums.common.GroupType;
import com.dashu.base.enums.common.PersonalType;
import com.dashu.base.enums.school.TeacherType;
import com.dashu.base.utils.CopyUtil;
import com.dashu.base.utils.UIDUtil;
import com.dashu.base.utils.VerificationUtil;
import com.dashu.core.dto.gate.GateGroupDTO;
import com.dashu.core.model.GateGroup;
import com.dashu.core.model.QGateGroup;
import com.dashu.core.vo.gate.GateGroupVO;
import com.querydsl.core.BooleanBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.FlushModeType;
import javax.transaction.Transactional;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class GateGroupService extends DataService {
    @Autowired
    private CompanyService companyService;
    @Autowired
    private CompanyDepartmentService companyDepartmentService;
    @Autowired
    private CompanyClsService companyClsService;
    @Autowired
    private CompanyTeacherService companyTeacherService;
    @Autowired
    private CompanyPersonalService companyPersonalService;

    @Transactional
    public GateGroupDTO add(GateGroupVO gateGroupVO) {
        GateGroup gateGroup = CopyUtil.copyEnty(gateGroupVO, GateGroup.class);
        try {
            long userId = Long.parseLong(VerificationUtil.getUserId());
            if (gateGroupVO.getId() == 0)
                gateGroup.setId(UIDUtil.nextId());
            if (gateGroupVO.getCreateUser() == 0)
                gateGroup.setCreateUser(userId);
            if (gateGroupVO.getCreateTime() == 0)
                gateGroup.setCreateTime(System.currentTimeMillis());
            gateGroup.setGroupType(GroupType.map.get(gateGroupVO.getGroupType()));
            gateGroup.setGroupName(gateGroupVO.getGroupName());
            gateGroup.setBaseId(gateGroupVO.getBaseId());
            gateGroup.setRuleId(gateGroupVO.getRuleId());
            if (gateGroupVO.getRuleType().equals("TEACHER")) {
                if (gateGroupVO.getGroupType().equals("PERSONAL")) {
                    companyTeacherService.updataGate(gateGroupVO.getBaseId(), gateGroupVO.getRuleId());
                } else {
                    TeacherType teacherTypes = TeacherType.map.get(gateGroupVO.getGroupType());
                    companyTeacherService.updataGateCompany(gateGroupVO.getBaseId(), gateGroupVO.getRuleId(), teacherTypes);
                }
            } else {
                List<PersonalType> personalTypes = CopyUtil.copyList(Arrays.asList(gateGroupVO.getRuleInType().split(",")), PersonalType.class);
                if (GroupType.COMPANY.equals(gateGroupVO.getGroupType()))
                    companyPersonalService.updataGateCompany(gateGroupVO.getBaseId(), gateGroupVO.getRuleId(), personalTypes);
                if (GroupType.DEPARTMENT.equals(gateGroupVO.getGroupType()))
                    companyPersonalService.updataGateDepartment(gateGroupVO.getBaseId(), gateGroupVO.getRuleId(), personalTypes);
                if (GroupType.CLS.equals(gateGroupVO.getGroupType()))
                    companyPersonalService.updataGateCls(gateGroupVO.getBaseId(), gateGroupVO.getRuleId(), personalTypes);
                if (GroupType.PERSONAL.equals(gateGroupVO.getGroupType()))
                    companyPersonalService.updataGatePersonal(gateGroupVO.getBaseId(), gateGroupVO.getRuleId());

                entityManager.persist(gateGroup);
//            entityManager.flush();
                entityManager.setFlushMode(FlushModeType.AUTO);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        GateGroupDTO gateGroupDTO = CopyUtil.copyEnty(gateGroup, GateGroupDTO.class);
        return gateGroupDTO;
    }

    @Transactional
    public boolean deleteGateGroup(long gateRuleId, String ruleType, String ruleInType) throws Exception {
        QGateGroup qGateGroup = QGateGroup.gateGroup;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(qGateGroup.ruleId.eq(gateRuleId));
        List<GateGroup> gateGroups =
                queryFactory
                        .select(qGateGroup)
                        .from(qGateGroup)
                        .where(booleanBuilder.getValue())
                        .fetch();
        for (GateGroup ag : gateGroups) {
            try {
                if (ruleType.equals("TEACHER")) {
                    if (ag.getGroupType().equals("PERSONAL")) {
                        companyTeacherService.updataGate(ag.getBaseId(), 0);
                    } else {
                        TeacherType teacherTypes = TeacherType.map.get(ag.getGroupType());
                        companyTeacherService.updataGateCompany(ag.getBaseId(), 0, teacherTypes);
                    }
                } else {
                    List<PersonalType> personalTypes = CopyUtil.copyList(Arrays.asList(ruleInType.split(",")), PersonalType.class);
                    if (GroupType.COMPANY.equals(ag.getGroupType())) {
                        companyPersonalService.updataGateCompany(ag.getBaseId(), 0, personalTypes);
                        if (GroupType.DEPARTMENT.equals(ag.getGroupType()))
                            companyPersonalService.updataGateDepartment(ag.getBaseId(), 0, personalTypes);
                        if (GroupType.CLS.equals(ag.getGroupType()))
                            companyPersonalService.updataGateCls(ag.getBaseId(), 0, personalTypes);
                        if (GroupType.PERSONAL.equals(ag.getGroupType()))
                            companyPersonalService.updataGatePersonal(ag.getBaseId(), 0);
                    }
                    entityManager.remove(ag);
//            entityManager.flush();
                    entityManager.setFlushMode(FlushModeType.AUTO);
                    return true;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    @Transactional
    public boolean updataGateGroup(List<GateGroupVO> gateGroupVOS, long gateRuleId, String ruleType, String ruleInType) throws Exception {
        deleteGateGroup(gateRuleId, ruleType, ruleInType);
        long userId = Long.parseLong(VerificationUtil.getUserId());
        gateGroupVOS.stream().forEach(ag -> {
            ag.setCreateTime(new Date().getTime());
            ag.setUpdateUser(userId);
            add(ag);
        });
        return true;

    }


  public  List<GateGroupDTO> findGateGroup(long gateRuleId) {
      QGateGroup qGateGroup = QGateGroup.gateGroup;
      BooleanBuilder booleanBuilder = new BooleanBuilder();
      booleanBuilder.and(qGateGroup.ruleId.eq(gateRuleId));
        List<GateGroup> gateGroups =
                queryFactory
                        .select(qGateGroup)
                        .from(qGateGroup)
                        .where(booleanBuilder.getValue())
                        .fetch();
      List<GateGroupDTO>  gateGroupDTOS = CopyUtil.copyList(gateGroups, GateGroupDTO.class);
        return gateGroupDTOS;

    }

}
